package com.hsl.hslcodemother.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.hsl.hslcodemother.mapper.AppMapper;
import com.hsl.hslcodemother.mapper.ChatHistoryMapper;
import com.hsl.hslcodemother.mapper.UserMapper;
import com.hsl.hslcodemother.model.dto.chathistory.ChatHistoryQueryRequest;
import com.hsl.hslcodemother.model.entity.App;
import com.hsl.hslcodemother.model.entity.ChatHistory;
import com.hsl.hslcodemother.model.entity.User;
import com.hsl.hslcodemother.model.enums.MessageTypeEnum;
import com.hsl.hslcodemother.model.vo.AppVO;
import com.hsl.hslcodemother.model.vo.ChatHistoryVO;
import com.hsl.hslcodemother.model.vo.UserVO;
import com.hsl.hslcodemother.service.AppService;
import com.hsl.hslcodemother.service.ChatHistoryService;
import com.hsl.hslcodemother.service.UserService;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 对话历史 服务层实现
 *
 * @author <a href="https://gitee.com/liul3">猴赛雷</a>
 */
@Service
public class ChatHistoryServiceImpl extends ServiceImpl<ChatHistoryMapper, ChatHistory> implements ChatHistoryService {

    @Resource
    private ChatHistoryMapper chatHistoryMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private AppMapper appMapper;

    @Resource
    private UserService userService;

    @Resource
    @Lazy
    private AppService appService;

    @Override
    public QueryWrapper getQueryWrapper(ChatHistoryQueryRequest chatHistoryQueryRequest) {
        QueryWrapper queryWrapper = QueryWrapper.create();
        if (chatHistoryQueryRequest == null) {
            return queryWrapper;
        }
        Long id = chatHistoryQueryRequest.getId();
        Long appId = chatHistoryQueryRequest.getAppId();
        Long userId = chatHistoryQueryRequest.getUserId();
        String messageType = chatHistoryQueryRequest.getMessageType();
        String content = chatHistoryQueryRequest.getContent();
        queryWrapper.eq(ChatHistory::getId, id)
                .eq(ChatHistory::getAppId, appId)
                .eq(ChatHistory::getUserId, userId)
                .eq(ChatHistory::getMessageType, messageType)
                .like(ChatHistory::getContent, content);
        return queryWrapper;
    }

    @Override
    public ChatHistoryVO getChatHistoryVO(ChatHistory chatHistory) {
        ChatHistoryVO chatHistoryVO = new ChatHistoryVO();
        BeanUtil.copyProperties(chatHistory, chatHistoryVO);
        return chatHistoryVO;
    }

    @Override
    public List<ChatHistoryVO> getChatHistoryVOList(List<ChatHistory> chatHistoryList) {
        if (CollUtil.isEmpty(chatHistoryList)) {
            return List.of();
        }
        return chatHistoryList.stream()
                .map(this::getChatHistoryVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<ChatHistoryVO> getLatestByAppId(Long appId, Integer pageNum, Integer pageSize) {
        if (appId == null || appId <= 0) {
            return List.of();
        }
        int offset = (pageNum - 1) * pageSize;
        List<ChatHistory> chatHistoryList = chatHistoryMapper.selectLatestByAppId(appId, pageSize, offset);
        List<ChatHistoryVO> chatHistoryVOList = getChatHistoryVOList(chatHistoryList);
        return fillAppAndUser(chatHistoryVOList);
    }

    @Override
    public Long countByAppId(Long appId) {
        if (appId == null || appId <= 0) {
            return 0L;
        }
        return chatHistoryMapper.countByAppId(appId);
    }

    @Override
    public boolean saveUserMessage(Long appId, Long userId, String content) {
        if (appId == null || appId <= 0 || userId == null || userId <= 0 || StrUtil.isBlank(content)) {
            return false;
        }
        ChatHistory chatHistory = ChatHistory.builder()
                .appId(appId)
                .userId(userId)
                .messageType(MessageTypeEnum.USER.getValue())
                .content(content)
                .build();
        return save(chatHistory);
    }

    @Override
    public boolean saveAiMessage(Long appId, Long userId, String content) {
        if (appId == null || appId <= 0 || userId == null || userId <= 0 || StrUtil.isBlank(content)) {
            return false;
        }
        ChatHistory chatHistory = ChatHistory.builder()
                .appId(appId)
                .userId(userId)
                .messageType(MessageTypeEnum.AI.getValue())
                .content(content)
                .build();
        return save(chatHistory);
    }

    @Override
    public boolean saveErrorMessage(Long appId, Long userId, String errorMessage) {
        if (appId == null || appId <= 0 || userId == null || userId <= 0 || StrUtil.isBlank(errorMessage)) {
            return false;
        }
        ChatHistory chatHistory = ChatHistory.builder()
                .appId(appId)
                .userId(userId)
                .messageType(MessageTypeEnum.ERROR.getValue())
                .content("AI回复失败")
                .errorMessage(errorMessage)
                .build();
        return save(chatHistory);
    }

    @Override
    public boolean deleteByAppId(Long appId) {
        if (appId == null || appId <= 0) {
            return false;
        }
        int result = chatHistoryMapper.deleteByAppId(appId);
        return result > 0;
    }

    @Override
    public List<ChatHistoryVO> fillAppAndUser(List<ChatHistoryVO> chatHistoryVOList) {
        if (CollUtil.isEmpty(chatHistoryVOList)) {
            return chatHistoryVOList;
        }
        // 收集所有应用ID和用户ID
        Set<Long> appIdSet = chatHistoryVOList.stream()
                .map(ChatHistoryVO::getAppId)
                .collect(Collectors.toSet());
        Set<Long> userIdSet = chatHistoryVOList.stream()
                .map(ChatHistoryVO::getUserId)
                .collect(Collectors.toSet());

        // 批量查询应用信息
        Map<Long, AppVO> appMap = appIdSet.stream()
                .collect(Collectors.toMap(
                        appId -> appId,
                        appId -> {
                            App app = appMapper.selectOneById(appId);
                            return app != null ? appService.getAppVO(app) : null;
                        }
                ));

        // 批量查询用户信息
        Map<Long, UserVO> userMap = userIdSet.stream()
                .collect(Collectors.toMap(
                        userId -> userId,
                        userId -> {
                            User user = userMapper.selectOneById(userId);
                            return user != null ? userService.getUserVO(user) : null;
                        }
                ));

        // 填充信息
        chatHistoryVOList.forEach(chatHistoryVO -> {
            chatHistoryVO.setApp(appMap.get(chatHistoryVO.getAppId()));
            chatHistoryVO.setUser(userMap.get(chatHistoryVO.getUserId()));
        });

        return chatHistoryVOList;
    }
}